第 6 章:分配 Pods 在對應 Nodes
決定 Pod 建立在哪個 Node 的過程
- 透過 api server 取得 node 信息
- node 選擇:filter > Scoring > Bind
- 更新 pod 的信息,包括在哪個 node 上
- 被選節點的 kubelet 透過監控 api-server 得知自己被選擇創造一個 pod
- kubelet 驅動 container runtime 建立 container 並啟動
Node Selector
- pods to Nodes using Labels and Selectors
- 給節點設定 label Apply Labels to Nodes
- Scheduler will assign Pods to a Node with a matchling Label
apiVersion: v1
kind: Pod
metadata:
name: web
spec:
containers:
- name: hello-world
image: nginx
nodeSelector:
hardware: local_gpu
為 Node 加上 Label
kubectl label nodes k8s-worker1 hardware=local_gpu
Affinity 親和性
Node Affinity
requiredDuringSchedulingIgnoredDuringExecution
- 如果執行的 pod 所在節點不再符合條件,kubernetes 會將 pod 從節點中刪除,重新選擇符合要求的節點
preferredDuringSchedulingIgnoredDuringExecution
- pod 部署之後運行的時候,如果節點標籤發生了變化,不再滿足 pod 指定的條件,pod 也會繼續運作
spec:
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: kubernetes.io/e2e-az-name
operator: In
values:
- e2e-az1
- e2e-az2
preferredDuringSchedulingIgnoredDuringExecution:
Pod Affinity
- 使用情境:我們系統服務 A 和服務 B 盡量部署在同個主機、機房、城市,因為它們網絡溝通比較多;再比如我們系統數據服務 C 和數據服務 D 盡量分開,因為如果它們分配在一起 ,然後主機或機房出了問題,會導致應用程式完全不可用,如果它們是分開的,應用程式雖然有影響,但還是可用的。
requiredDuringSchedulingIgnoredDuringExecution
preferredDuringSchedulingIgnoredDuringExecution
spec:
affinity:
podAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
podAntiAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
Taints
Node affinity 使得 pod 有选择 node 的能力. Taints 正好相反
kubectl taint nodes g8node1 size=large:NoSchedule
effect 欄位:當Pod因為此Taint而無法調度到該節點上的時候,該怎麼處理
- NoSchedule
- 若在剩餘
Taints
中存在effect=NoSchedule
,則調度器不會把該Pod
調度到此節點上
- 若在剩餘
- PreferNoSchedule
- 若在剩餘
Taints
中沒有effect=NoSchedule
,但有PreferNoSchedule
,則會試著不把該Pod調度到此節點
- 若在剩餘
- NoExcute
- 若在剩餘
Taints
中有effect=NoExcute
,並且該Pod
已經在此節點上運行,則會被驅逐;若沒有在此節點上運行,也不會再被調度到此節點上
- 若在剩餘
在特定情境下,內建的 taints 會運行
node.kubernetes.io/not-ready
: Node is not ready. This corresponds to the NodeConditionReady
being "False
".node.kubernetes.io/unreachable
: Node is unreachable from the node controller. This corresponds to the NodeConditionReady
being "Unknown
".node.kubernetes.io/memory-pressure
: Node has memory pressure.node.kubernetes.io/disk-pressure
: Node has disk pressure.node.kubernetes.io/pid-pressure
: Node has PID pressure.node.kubernetes.io/network-unavailable
: Node's network is unavailable.node.kubernetes.io/unschedulable
: Node is unschedulable.node.cloudprovider.kubernetes.io/uninitialized
: When the kubelet is started with "external" cloud provider, this taint is set on a node to mark it as unusable. After a controller from the cloud-controller-manager initializes this node, the kubelet removes this taint.
Tolerations
Tolerations are applied to pods. Tolerations allow the scheduler to schedule pods with matching taints
Pod
的Toleration
宣告中的key
和effect
需要與Taint
的設定保持一致,並滿足以下條件之一:
operator
的值是Exists
( 無須指定 value )operator
的值是Equal
且value值相等
Cordoning
Cordoning 是把一個節點標記為 unschedulabel, 一旦標記後,就不會再有新的 pod 被部署到這個節點上了。 但已經運行在這個節點的 pod 不受影響。
- Drain
- drain 可以 gracefully 的停止一個節點上的 Pod
kubectl cordon $NODE
- Uncordon
- 重新標記一個節點為 schedulable
kubectl drain $NODE --ingore-daemonsets
Manual Scheduling
就是直接手動決定 pod 運行在哪個 Node
- taint 的 node 是否可以接受這種 pod? yes
- cordon 的 node 是否可以接受這種 pod? yes
apiVersion: v1
kind: Pod
metadata:
name: web
spec:
nodeName: 'k8s-worker1'
containers:
- name: nginx-container
image: nginx:latest